<?php
require ('AwsSignatureV4.php');
require ('Http.php');
/**
 * AmazonS3 API接口参考代码
 * 参考:
 * https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html
 * https://docs.aws.amazon.com/zh_cn/AmazonS3/latest/API/archive-sig-v4-header-based-auth.html
 * https://docs.aws.amazon.com/AmazonS3/latest/API/archive-RESTObjectPUTacl.html
 */
class AmazonS3Api {
	/**
	 * 设置对象的ACL（访问权限）
	 * @param unknown $endpoint
	 * @param unknown $bucket
	 * @param unknown $accessKey
	 * @param unknown $secretKey
	 * @param unknown $fileResource  对象（文件）
	 * @param unknown $acl   ACL值（xml格式）
	 * @return string|mixed
	 */
	public static function setObjectAcl($endpoint, $bucket, $accessKey, $secretKey, $fileResource, $acl) {
		$s3v4 = new AwsSignatureV4 ();
		$date = $s3v4->getDate ();
		$dateTime = $s3v4->getDateTime ();
		// 设置请求参数，注意设置的顺序要按照英文字符从小到大排序
		$queryParams = array (
				"acl" => "" 
		);
		// 设置请求头，注意设置的顺序要按照英文字符从小到大排序
		$headers = array (
				"Content-Type" => "application/xml",
				"Host" => $s3v4->resolveEndpoint ( $endpoint, $bucket, "h" ),
				"x-amz-content-sha256" => "UNSIGNED-PAYLOAD",
				"X-Amz-Date" => $dateTime 
		);
		$httpMethod = "PUT";
		// 生成s3v4签名
		$sign = $s3v4->createSign ( $endpoint, $bucket, $accessKey, $secretKey, $fileResource, $httpMethod, $date, $dateTime, $queryParams, $headers );
		// 生成请求头Authorization
		$Authorization = $s3v4->createAuthorizationHeader ( $accessKey, $date, $headers, $sign );
		$headers ["Authorization"] = $Authorization;
		// 生成S3 API服务的url地址
		$url = self::requestPathLinkResource ( $s3v4, $endpoint, $bucket, $fileResource ) . "?acl";
		return self::doPut($url,$headers,$acl);
	}
	
	
	/**
	 * url进行预签名
	 * @param unknown $endpoint
	 * @param unknown $bucket
	 * @param unknown $accessKey
	 * @param unknown $secretKey
	 * @param unknown $fileResource  文件名称
	 * @param unknown $expires 失效时间 ，单位毫秒
	 * @return string  预签名后的url
	 */
	public static function presignRequest($endpoint, $bucket, $accessKey, $secretKey, $fileResource, $expires) {
		$s3v4 = new AwsSignatureV4 ();
		$date = $s3v4->getDate ();
		$dateTime = $s3v4->getDateTime ();
		// 设置请求参数，注意设置的顺序要按照英文字符从小到大排序
		$queryParams = array (
				"X-Amz-Algorithm" => "AWS4-HMAC-SHA256",
				"X-Amz-Credential" => $accessKey . "%2F" . $date . "%2F" . AwsSignatureV4::$region . "%2F" . AwsSignatureV4::$service . "%2F" . "aws4_request",
				"X-Amz-Date" => $dateTime,
				"X-Amz-Expires" => $expires,
				"X-Amz-SignedHeaders" => "host"
		);
		// 设置请求头，注意设置的顺序要按照英文字符从小到大排序
		$headers = array (
				"Host" => $s3v4->resolveEndpoint ( $endpoint, $bucket, "h" )
		);
		$httpMethod = "PUT";
		// 生成s3v4签名
		$sign = $s3v4->createSign ( $endpoint, $bucket, $accessKey, $secretKey, $fileResource, $httpMethod, $date, $dateTime, $queryParams, $headers );
		// 生成S3 API服务的url地址
		$presignRequest = self::requestPathLinkResource($s3v4, $endpoint, $bucket, $fileResource) . "?";
		foreach ( $queryParams as $key => $value ) {
			$presignRequest = $presignRequest.$key."=".$value."&";
		}
		$presignRequest = $presignRequest."X-Amz-Signature=".$sign;
		return $presignRequest;
	}
	

	/**
	 * 拼接endpoint、$bucket、fileResource得到S3 API服务的url地址
	 * @param AwsSignatureV4 $s3v4
	 * @param unknown $endpoint
	 * @param unknown $bucket
	 * @param unknown $fileResource
	 * @return string
	 */
	static function requestPathLinkResource(AwsSignatureV4 $s3v4, $endpoint, $bucket, $fileResource) {
		// 解析出新的path路径
		$requestPath = $s3v4->resolveEndpoint ( $endpoint, $bucket, "p" );
		if (! $s3v4->startwith ( $fileResource, "/" )) { // 资源的路径不是以/开头的，就要拼接上/
			$fileResource = "/" . $fileResource;
		}
		return $requestPath . $fileResource;
	}
	
	static function doPut($url, $signHeaders, $reqBody) {
		$http = new Http ();
		$headers = array ();
		foreach ( $signHeaders as $key => $value ) {
			$headers [] = $key . ":" . $value;
		}
		$httpOptions = array (
				CURLOPT_HTTPHEADER => $headers
		);
		$result = $http->doPut ( $url, $reqBody, $httpOptions );
		return $result;
	}
	
}

?>
    
   
    